package com.dongzili.postgresql.common.mybatisplus.postgresql;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.*;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.util.Properties;

/**
 * Postgres方言符号替换
 */
@Intercepts({
    @Signature(
        type = StatementHandler.class,
        method = "prepare",
        args = {Connection.class, Integer.class}
    )
})
public class SqlBacktickRemoverInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        // 获取拦截方法的参数：第一个参数是Connection
        Connection connection = (Connection) invocation.getArgs()[0];
        // 获取数据库元数据
        DatabaseMetaData metaData = connection.getMetaData();
        // 获取数据库产品名称（如 "PostgreSQL"、"MySQL"、"Oracle"）
        String databaseProductName = metaData.getDatabaseProductName();
        // 获取数据库版本（可选）
//        String databaseVersion = metaData.getDatabaseProductVersion();
        if (!databaseProductName.equalsIgnoreCase("PostgreSQL")){
            return invocation.proceed();
        }
        // 获取StatementHandler对象
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        BoundSql boundSql = statementHandler.getBoundSql();
        // 获取原始SQL
        Field sqlField = boundSql.getClass().getDeclaredField("sql");
        sqlField.setAccessible(true);
        String originalSql = (String) sqlField.get(boundSql);
        System.err.println("原始SQL: " + originalSql);
        // 替换反引号
        String newSql = originalSql.replace("`", "\"");
        // 反射设置修改后的SQL
        sqlField.set(boundSql, newSql);
        // 继续执行原方法
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        // 只对StatementHandler进行拦截增强
        if (target instanceof StatementHandler) {
            return Plugin.wrap(target, this);
        }
        return target;
    }

    @Override
    public void setProperties(Properties properties) {
        // 可以通过properties配置参数
    }
}
    